package com.share.shareplatform.sharegoods.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.share.shareplatform.common.state.GoodsKind;
import com.share.shareplatform.pojo.Goods;
import com.share.shareplatform.pojo.GoodsSpecial;
import com.share.shareplatform.pojo.Repertory;
import com.share.shareplatform.pojo.exception.LogicException;
import com.share.shareplatform.sharegoods.dao.GoodsDao;
import com.share.shareplatform.sharegoods.service.GoodsService;
import com.share.shareplatform.util.Result;
import io.seata.spring.annotation.GlobalLock;
import io.seata.spring.annotation.GlobalTransactional;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service("goodsService")
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private GoodsDao goodsDao;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public Long addOne(Goods goods) {
        return goodsDao.addOne(goods);
    }


    @Override
    public Integer updateOne(Goods goods) {
        return goodsDao.updateOne(goods);
    }

    @Override
    public Integer deleteOneById(Long id) {
        return goodsDao.deleteOneById(id);
    }

    @Override
    public Integer deleteAllByIds(List<Long> ids) {
        return goodsDao.deleteAllByIds(ids);
    }

    @Override
    public Goods findOneById(Long id) {
        return goodsDao.findOneById(id);
    }

    @Override
    public List<Goods> findAllByShopId(Long shopId) {
        return goodsDao.findAllByShopId(shopId);
    }

    @Override
    public List<Goods> findPage(Integer pageIndex, Integer pageSize) {
        return goodsDao.findPage((pageIndex-1)*pageSize,pageSize);
    }

    @Override
    public Goods findSpecialOneById(Long id) {
        return goodsDao.findOneSpecialById(id);
    }

    @Override
    public Long addSpecialOne(GoodsSpecial goodsSpecial) {
        return goodsDao.addOneSpecial(goodsSpecial);
    }

    @Override
    public List<GoodsSpecial> findAllSpecialByKind(String kind) {
        if(!GoodsKind.search(kind)){
            throw new LogicException("没有该类型");
        }
        String redisName=GoodsKind.searchRedisName(kind);
        List list= redisTemplate.opsForList().range(redisName,0,-1);
        if(list==null||list.size()==0){
            list=goodsDao.findAllSpecialByKind(kind);
            redisTemplate.opsForList().rightPushAll(redisName,list);
        }
        return list;
    }

    @Override
    public Result findAllSpecial() {
        List newList= redisTemplate.opsForList().range("newList",0,-1);
        if(newList==null||newList.size()==0){
            newList=findAllSpecialByKind(GoodsKind.NEW.getKind());
            redisTemplate.opsForList().rightPushAll("newList",newList);
        }

        List hotList= redisTemplate.opsForList().range("hotList",0,-1);
        if(hotList==null||hotList.size()==0){
            hotList=findAllSpecialByKind(GoodsKind.HOT.getKind());
            redisTemplate.opsForList().rightPushAll("hotList",hotList);
        }

        List recommendList= redisTemplate.opsForList().range("recommendList",0,-1);
        if(recommendList==null||recommendList.size()==0){
            recommendList=findAllSpecialByKind(GoodsKind.RECOMMEND.getKind());
            redisTemplate.opsForList().rightPushAll("recommendList",recommendList);
        }
        return Result.getInstance(200,"success").
                put("newList",newList).put("hotList",hotList).put("recommendList",recommendList);
    }

    @Override
    public Integer deleteOneSpecialById(Long id) {
        return goodsDao.deleteOneSpecialById(id);
    }

    @Override
    @GlobalLock
    public int updateAllRepertory(List<Repertory> list) {
        if(list.size()==0){
            throw new LogicException("扣减库存异常");
        }
        int i = goodsDao.updateAllRepertory(list);
        if(list.size()!=i){
            throw new LogicException("扣减失败");
        }
        //int t=1/0;
        return i;
    }

    @Override
    public List<Goods> findDimAllByName(String name) {
        return goodsDao.findAllDimByName(name);
    }

    @Override
    public List<Goods> findAllByBrandId(Long id) {
        return goodsDao.findAllByBrandId(id);
    }

    @Override
    public List<Goods> findAllByTypeId(Long id) {
        return goodsDao.findAllByTypeId(id);
    }

    @Override
    public List<Goods>  findPageByName(String name,Integer pageIndex,Integer pageSize) throws IOException {

        //条件搜索
        SearchRequest searchRequest=new SearchRequest("goods");
        SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();

        //分页
        sourceBuilder.from((pageIndex-1)*pageSize);
        sourceBuilder.size(pageSize);

        //模糊匹配
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", name);
        sourceBuilder.query(matchQuery);

        //设置源字段过虑,第一个参数结果集包括哪些字段，第二个参数表示结果集不包括哪些字段
        sourceBuilder.fetchSource(Goods.fields,null);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        //执行搜索
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        ArrayList<Goods> list=new ArrayList<>();
        for(SearchHit documentFields:searchResponse.getHits().getHits()){
            //Map<String , HighlightField> highlightFields=documentFields.getHighlightFields();
            //HighlightField title=highlightFields.get("title");
            Map<String,Object> sourceAsMap=documentFields.getSourceAsMap();//原来的结果
            System.out.println(sourceAsMap);
            Goods goods = objectMapper.convertValue(sourceAsMap, Goods.class);

            //解析高亮字段，将原来的字段替换成高亮的字段即可
            /*if(title!=null){
                Text[] fragments=title.fragments();
                String n_title="";
                for(Text text:fragments){
                    n_title+=text;
                }
                sourceAsMap.put("title",n_title);//高亮字段替换原来的内容
            }*/
            list.add(goods);
        }
        return list;
    }

    public Map<Long,Goods>  findAllByIdAsMap(String ids) {
        String[] stringIds=ids.split("-");

        ArrayList<Long> arrayList=new ArrayList<>();
        for(String id:stringIds){
            arrayList.add(Long.parseLong(id));
        }
        Map<Long, Goods> map = goodsDao.findAllByIdAsMap(arrayList);
        return map;
    }
}
